<template>
  <div class="main-warper">
    <div v-permission="'file:upload'">
      <!-- <el-upload class="upload-demo" drag :headers="tokenHeader"
        :action="baseURL + '/file/upload?path=' + data.fileData.currentPath" :on-success="handleUploadSuccess" multiple>
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          拖放文件 <em>或者点击此处上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            单个文件限制4G
          </div>
        </template>
      </el-upload> -->
      <el-upload class="upload-demo" drag multiple :auto-upload="false"
        action="#" :on-change="handleChange" :on-remove="handleRemove">
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          拖放文件 <em>或者点击此处上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            <!-- 单个文件限制2G 总文件限制10G -->
            单个文件限制4G
          </div>
        </template>
      </el-upload>
      <el-row>
    <el-table :data="tableData" stripe style="width: 100%">
      <el-table-column prop="name" label="名字"/>
      <el-table-column prop="percentage" label="进度">
        <template #default="scope">
          <el-progress :text-inside="true" :stroke-width="26" :percentage="scope.row.percentage" />
      </template>
      </el-table-column>
      <el-table-column prop="percentage" label="操作">
        <template #default="scope">
          <el-button type="primary" @click="handleRemoveUploadFileList(scope.row)">删除</el-button>
      </template>
      </el-table-column>
    </el-table>
  </el-row>

    </div>
    <el-affix :offset="0">
      <el-breadcrumb :separator-icon="ArrowRight" class="breadcrumb">
        <el-breadcrumb-item :to="{ path: 'file', query: { path: '/' } }">我的资源</el-breadcrumb-item>
        <el-breadcrumb-item v-for="dir in data.dir" :to="{ path: 'file', query: { path: dir.path } }">{{ dir.name
        }}</el-breadcrumb-item>
      </el-breadcrumb>
    </el-affix>
    <table class="table" v-if="!isMobile()">
      <thead class="table-header">
        <tr class="click-fix">
          <th style="max-width: 660px;cursor: pointer;text-decoration: underline;" @click="sortBy('fileName')">文件名</th>
          <th style="cursor: pointer;text-decoration: underline;" @click="sortBy('fileCreateTime')">修改时间
          </th>
          <th style="cursor: pointer;text-decoration: underline;" @click="sortBy('fileSize')">文件大小</th>
          <th style="max-width: 426px;">操作</th>
        </tr>
      </thead>
      <tbody class="table-body custom-loading-svg" v-loading="loading" style="width: 100%">
        <tr>
          <td colspan="4" class="table-title"><el-empty description="没有数据" :image-size="350"
              v-if="data.isEmpty" class="empty" /></td>
        </tr>
        <tr v-for="item in data.fileData.fileList" class="table-row">
          <td class="table-item" @click="handleProcess(item)">
            <div class="item-link" :style="{cursor:data.avaibleType.includes(item.fileType)||item.isDir?'pointer':'default'}">
              <img :src="getItemImg(item)" class="item-icon" alt="" @click="handleProcess(item)"/>
                <span>{{ item.fileName }}</span>
            </div>
          </td>
          <td>{{ item.createTime }}</td>
          <td v-if="!item.isDir">{{ formatSize(item.fileSize) }}</td>
          <td v-else></td>

          <td class="table-item-btn"><el-button class="btn-group" v-if="data.avaibleType.includes(item.fileType)"
              type="primary" @click="handlePreview(item.fileName, item.fileType)">预览</el-button>

            <el-button class="btn-group" v-if="!item.isDir" type="success"
              @click="handleDown(item.fileName)">下载</el-button><el-button class="btn-group" type="danger"
              v-permission="'file:delete'" @click="handleDel(item.fileName)">删除</el-button>
            <el-button class="btn-group" type="warning" v-permission="'file:rename'"
              @click="handleRename(item.fileName)">重命名</el-button>
            <el-button class="btn-group" type="info" v-permission="'file:copy'"
              @click="handleCopy(item.fileName)">复制</el-button>
            <el-button class="btn-group" type="primary" v-permission="'file:cut'"
              @click="handleCut(item.fileName)">剪切</el-button>
          </td>
        </tr>

      </tbody>
    </table>
    <!--手机端-->
    <ul class="ul-mobile" v-if="isMobile()" v-loading="loading">
      <el-empty description="没有数据" :image-size="350"
              v-if="data.isEmpty" class="empty" />
      <el-radio-group>
      <li v-for="item in data.fileData.fileList" class="li-row">
        <div class="li-item">
            <div class="li-item-icon"  @click="handleProcess(item)"><img class="li-item-icon-img" :src="getItemImg(item)" alt="" /></div> 
            <div class="li-item-text">
              <span class="li-item-text-name"  @click="handleProcess(item)"> {{ item.fileName }} </span>
              <span class="li-item-text-time">{{ item.createTime }}</span>
            </div>
            <div class="li-item-btn">
              <el-radio v-model="item.checked" style="height: 48px;width: 48px;"  @click="handleTouch(item)" />
            </div>
        </div>

      </li>
    </el-radio-group>
    </ul>
    <el-backtop :bottom="100">
      <div style="
        height: 100%;
        width: 100%;
        background-color: var(--el-bg-color-overlay);
        box-shadow: var(--el-box-shadow-lighter);
        text-align: center;
        line-height: 40px;
        color: #1989fa;
      ">
        ↑
      </div>
    </el-backtop>

    <el-dialog width="80%" :title="data.operate == 1 ? '重命名' : '新建文件夹'" v-model="data.formVisible" @close="data.formVisible = false"
      @cancel="data.formVisible = false">
      <el-form label-width="100px" :model="data.form" label-position="top">
        <el-form-item :label="data.operate == 1 ? '文件名' : '文件夹名'">
          <el-input v-model="data.form.newFileName" placeholder="请输入名称" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="data.formVisible = false">取消</el-button>
          <el-button type="primary"
            @click="data.formVisible = false; data.operate == 1 ? handleRenameConfirm() : handleNewDirConfirm()">
            确认
          </el-button>
        </span>
      </template>
    </el-dialog>

    <preview ref="prevRef" :url="url" :type="type"></preview>
    <el-button v-if="data.clipboard.file !== ''" @click="handlePaste()" class="btn-paste"><el-icon :size="20"><CopyDocument /></el-icon></el-button>
    <el-button v-permission="'file:new:dir'" @click="handleNewDir()" class="btn-new-dir"><el-icon :size="20"><FolderAdd /></el-icon></el-button>


    <el-drawer v-model="data.showDrawer" direction="btt">
      <template #header>
        <h5>{{ data.file.current.fileName }}</h5>
      </template>
      <template #default>
        <div class="btn-group-drawer">
          <el-button class="mobile" v-if="!data.file.current.isDir" type="success"
            @click="handleDown(data.file.current.fileName);data.showDrawer=false;">下载</el-button><el-button class="mobile" type="danger"
            v-permission="'file:delete'" @click="handleDel(data.file.current.fileName);data.showDrawer=false;">删除</el-button>
          <el-button class="mobile" type="warning" v-permission="'file:rename'"
            @click="handleRename(data.file.current.fileName);data.showDrawer=false;">重命名</el-button>
          <el-button class="mobile" type="info" v-permission="'file:copy'"
            @click="handleCopy(data.file.current.fileName);data.showDrawer=false;">复制</el-button>
          <el-button class="mobile" type="primary" v-permission="'file:cut'"
            @click="handleCut(data.file.current.fileName);data.showDrawer=false;">剪切</el-button>
        </div>
      </template>
    </el-drawer>


  </div>
</template>

<script setup lang="ts">
import config from '@/utils/config'
const baseURL = config.baseURL
import { ArrowRight } from '@element-plus/icons-vue'
import { useRoute, onBeforeRouteUpdate,useRouter } from 'vue-router';
import { reactive, onMounted, ref } from 'vue';
import Preview from '@/components/Preview/index.vue'
import { listFilePath, delFile, renameFile, copyFile, cutFile, newDir,uploadFileChunks,uploadFile,mergeFile } from '@/apis/hyfile';
import { ElMessage, ElMessageBox } from 'element-plus';
import { ElNotification } from 'element-plus'
import { getPermissonList } from '@/apis/user';
import useStore from '@/store';
import { type UploadProps, UploadFile, UploadFiles } from 'element-plus'

const { user } = useStore();
const route = useRoute();
const router = useRouter();
const loading = ref(false)
const url = ref("")
const type = ref("")


const data = reactive({
  fileData: {} as HyFileBase,
  formVisible: false,
  operate: 0,//1为重命名，2为新建文件夹
  dir: [],
  isEmpty: true,
  file: {
    current: {} as HyFile,
    fileList: [],
    dirList: [],
  },
  clipboard: {
    file: '',
    opt: '',
    done: 0,
  },
  showDrawer: false,
  avaibleType: ['jpg', 'jpeg', 'bmp', 'png', 'gif', 'mp4', 'wav', 'webm', 'mp3', 'ogg', 'webp','flac','swf'],
  form: {
    oldFileRealPath: '',
    oldFileName: '',
    newFileName: '',
    newFileRealPath: '',
  },
  touchTimer: null,
  touchShorterTimer:null,
  loaded: false,
  contextmenuVisible: false,

});

const prevRef = ref(null)
const handleShow = () => {
  prevRef.value.show()
}
onBeforeRouteUpdate(to => {
  if(to.query.path === undefined || to.query.path === 'undefined' || to.query.path === '') to.query.path = '/'
  fetchNewDir(to.query.path as string)
})

onMounted(() => {

  getPermissonList().then(res => { user.setPerm(res.data); fetchNewDir((route.query.path ? route.query.path : '/') as string) })

})
function isMobile() {
  return window.innerWidth <= 767;
}
function fetchNewDir(path: string) {
  loading.value = true;

  listFilePath(path).then(resp => {
    data.fileData.fileList = resp.data.data.fileList;
    data.fileData.currentPath = resp.data.data.currentPath;
    data.fileData.total = resp.data.data.total;
    data.fileData.dirList = resp.data.data.dirList;
    data.dir = data.fileData.dirList;
    data.isEmpty = data.fileData.fileList.length == 0;
    loading.value = false
  });
 
}
function handleDel(fileName: string) {

  ElMessageBox.confirm(
    '将要删除' + fileName + '，是否继续?',
    '警告',
    {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(() => {
    delFile(fullPath(fileName)).then(resp => {
      if (resp.data.code == 200) {
        ElMessage({
          message: '删除成功',
          type: 'success'
        })
      }
      fetchNewDir(data.fileData.currentPath)
    })

  }).catch(() => {
    ElMessage({
      type: 'info',
      message: '取消操作',
    });
  })



}
function handleDown(fileName: string) {
  window.open(baseURL + '/download?path=' + fullPath(fileName))
}
function handlePreview(fileName: string, t: string) {
  url.value = baseURL + '/getVideo?path=' + fullPath(fileName)
  type.value = t
  handleShow()
}

function fullPath(fileName: string) {
  if (data.fileData.currentPath != '/') {
    return data.fileData.currentPath + "/" + fileName;
  } else {
    return "/" + fileName;
  }
}


function handleRename(fileName: string) {
  data.operate = 1;
  data.formVisible = true;
  data.form.oldFileName = fileName;
  data.form.oldFileRealPath = fullPath(fileName);
  data.form.newFileName = fileName;
}
function handleRenameConfirm() {
  if (data.form.newFileName == null || data.form.newFileName == '') {
    ElMessage({
      message: '文件名不能为空',
      type: 'error'
    })
    return
  } else {

    renameFile(fullPath(data.form.oldFileName), fullPath(data.form.newFileName)).then(resp => {
      if (resp.data.code == 200) {
        ElMessage({
          message: '重命名成功',
          type: 'success'
        })
      }
      data.formVisible = false;
      fetchNewDir(data.fileData.currentPath)
    })
  }
}
function handleNewDir() {
  data.form.newFileName = '';
  data.operate = 2;
  data.formVisible = true;
}
function handleNewDirConfirm() {
  if (data.form.newFileName == null || data.form.newFileName == '') {
    ElMessage({
      message: '文件名不能为空',
      type: 'error'
    })
    return
  } else {

    newDir(data.form.newFileName, data.fileData.currentPath).then(resp => {
      if (resp.data.code == 200) {
        ElMessage({
          message: '新建文件夹成功',
          type: 'success'
        })
      }
      data.formVisible = false;
      fetchNewDir(data.fileData.currentPath)
    })
  }
}

function handlePaste() {
  const copyPath = data.clipboard.file
  if (copyPath) {
    ElMessageBox.confirm(
      '将要粘贴' + copyPath + '，是否继续?',
      '警告',
      {
        confirmButtonText: '粘贴',
        cancelButtonText: '取消',
        type: 'warning',
      }
    ).then(() => {
      let notifiction = null;
      if (data.clipboard.opt == 'copy') {
        notifiction = ElNotification({
          title: '仍在复制中...',
          message: 'Reng Zai Copying',
          type: 'warning',
          duration: 0,
        })
        copyFile(copyPath, data.fileData.currentPath).then(resp => {
          notifiction.close()
          if (resp.data.code == 200) {
            ElMessage({
              message: '粘贴成功',
              type: 'success'
            })
          }
          data.clipboard.file = ''
        }).then(() => {
          fetchNewDir(data.fileData.currentPath)
        })

      } else if (data.clipboard.opt == 'cut') {
        notifiction = ElNotification({
          title: '仍在剪切中...',
          message: 'Reng Zai Cutting',
          type: 'warning',
          duration: 0,
        })
        cutFile(copyPath, data.fileData.currentPath).then(resp => {
          if (resp.data.code == 200) {
            notifiction.close()
            ElMessage({
              message: '剪切成功',
              type: 'success'
            })
          }
          data.clipboard.file = ''
        }).then(() => {
          fetchNewDir(data.fileData.currentPath)
        })
      } else {
        ElMessage({
          message: '未知操作',
          type: 'error'
        })
      }
    })

  }
}
function handleCopy(fileName: string) {
  data.clipboard.opt = 'copy'
  data.clipboard.file = fullPath(fileName)
}
function handleCut(fileName: string) {
  data.clipboard.opt = 'cut'
  data.clipboard.file = fullPath(fileName)
}
const fileList  = ref<UploadFiles>([]);
const tableData = ref<UploadFiles>([]);
const handleChange:UploadProps['onChange'] = async (uploadFile, uploadFiles) => {
  //准备写大文件分片上传
  tableData.value.push({ ...uploadFile })
  const index = tableData.value.findIndex(item => item.uid === uploadFile.uid)
  //分块大小 32M  
  const chunkSize = 1024 * 1024 * 32;
  if(uploadFile.size < chunkSize){
      //执行普通上传不分片
      //upload(file,0,1,fileName,path);
      handleUploadSimple(uploadFile.raw,uploadFile.name,data.fileData.currentPath,index)
  }else{
    const chunkTotal = Math.ceil(uploadFile.size / chunkSize);

    for(let i = 0;i < chunkTotal;i++){
      const start = i * chunkSize;
      const end = start + chunkSize;
      const chunk = uploadFile.raw.slice(start,end);
      // console.log(chunk)
      const chunkFile = new File([chunk],uploadFile.name + '-' + i);
      
      const result = await handleUploadChunks(chunkFile,i,chunkTotal,uploadFile.name,data.fileData.currentPath,index);
      console.log(result);
    }
    handleMergeFile(uploadFile.name,data.fileData.currentPath,chunkTotal);
  }


}


async function handleUploadChunks(file:Blob,chunkIdx:number,chunkTotal:number,fileName:string,path:string,index:number){
  const form = new FormData();

  // 构造一个form对象
  form.append("file",file);
  form.append("path",path);
  form.append("chunkIdx",chunkIdx.toString());
  form.append("chunkTotal",chunkTotal.toString());
  form.append("fileName",fileName);
  
  
  const result = await uploadFileChunks(form)
  tableData.value[index].percentage =  ((chunkIdx+1) / chunkTotal * 100);
 
  return result;
}
async function handleUploadSimple(file:any,fileName:string,path:string,index:number){
  const form = new FormData();
  // 构造一个form对象
  form.append("file",file);
  form.append("path",path);
  form.append("fileName",fileName);
  const result = await uploadFile(form,(progressEvent)=>{
    tableData.value[index].percentage =  progressEvent.loaded / progressEvent.total * 100;
  });
  handleUploadSuccess();
  return result;
}

function handleMergeFile(fileName:string,path:string,chunkTotal:number){
  const form = new FormData();
  form.append("path",path);
  form.append("chunkTotal",chunkTotal.toString());
  form.append("fileName",fileName);
  mergeFile(form).then(resp => {
    if (resp.data.code == 200) {
      handleUploadSuccess()
    }
  })
}

/**
 * 从el-upload封装的文件列表中删除文件
 * // el-upload的（内置方法），点击el-upload默认的文件展示以列表的 X 那个图标时，会移除文件，并从文件列表中去掉
 * @param uploadFile el-upload当前删除点击的文件
 * @param uploadFiles el-upload的文件列表
 */
 const handleRemove: UploadProps['onRemove'] = async (uploadFile, uploadFiles) => {
  // 这个删除表格tableData中的列表数据
  const index2 = tableData.value.findIndex((item2: UploadFile) => item2.uid === uploadFile.uid)
  if (index2 !== -1) {
    tableData.value.splice(index2, 1)
  }
  await handleDel(uploadFile.name)

  console.log(uploadFiles)
}



/**
 * 自定义的表格删除的方法
 * @param file 表格某一行的数据
 */
const handleRemoveUploadFileList = async (file: UploadFile) => {
  const index = fileList.value.findIndex((item: UploadFile) => item.uid === file.uid)
  if (index !== -1) {
    fileList.value.splice(index, 1)
  }
  const index2 = tableData.value.findIndex((item2: UploadFile) => item2.uid === file.uid)
  if (index2 !== -1) {
    tableData.value.splice(index2, 1)
  }

  // 删除磁盘中的文件
  await handleDel(file.name)
}



function getItemImg(item: HyFile) {
  if (item.isDir) {
    return '/icon/floder.png'
  } else {
    switch (item.fileType) {
      case 'jpg':
      case 'jpeg':
      case 'png':
      case 'gif':
      case 'webp':
        return '/icon/picture.png'
      case 'mp3':
      case 'wav':
      case 'flac':
      case 'ogg':
      case 'wma':
      case 'ape':
      case 'm4a':
      case 'aac':
        return '/icon/music.png'
      case 'txt':
        return '/icon/txt.png'
      case 'pdf':
        return '/icon/pdf.png'
      case 'doc':
      case 'docx':
        return '/icon/word.png'
      case 'xls':
      case 'xlsx':
        return '/icon/excel.png'
      case 'exe':
        return '/icon/exe.png'
      case 'zip':
      case 'rar':
      case '7z':
        return '/icon/yasuo.png'
      case 'ppt':
      case 'pptx':
        return '/icon/ppt.png'
      case 'torrent':
        return '/icon/bt.png'
      case 'css':
      case 'php':
      case 'htm':
      case 'html':
      case 'c':
      case 'java':
      case 'e':
      case 'go':
      case 'ts':
      case 'js':
      case 'py':
      case 'sh':
      case 'bat':
      case 'c#':
      case 'vb':
      case 'cs':
      case 'cpp':
      case 'sql':
      case 'json':
      case 'xml':
      case 'yml':
      case 'yaml':
      case 'toml':
      case 'md':
      case 'markdown':
      case 'log':
        return '/icon/code.png'
      default:
        return '/icon/other.png'


    }
  }
}
function formatSize(size: number) {
  if (size < 1024) {
    return size + 'B'
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + 'KB'
  } else if (size < 1024 * 1024 * 1024) {
    return (size / 1024 / 1024).toFixed(2) + 'MB'
  } else {
    return (size / 1024 / 1024 / 1024).toFixed(2) + 'GB'
  }
}

function handleUploadSuccess() {
  ElMessage({
    message: '上传成功',
    type: 'success'
  })
  fetchNewDir(data.fileData.currentPath)
}
let flag = true;
function sortBy(key: string) {
  data.file.fileList = []
  data.file.dirList = []
  data.fileData.fileList.forEach(item => {
    if (item.isDir) {
      data.file.dirList.push(item)
    } else {
      data.file.fileList.push(item)
    }

  })
  flag = !flag;
  data.file.fileList = sortByKey(data.file.fileList, key, flag)
  data.file.dirList = sortByKey(data.file.dirList, key, flag)
  if (flag) {
    data.fileData.fileList = data.file.dirList.concat(data.file.fileList)
  } else {
    data.fileData.fileList = data.file.fileList.concat(data.file.dirList)
  }

}
function handleProcess(file:HyFile){
  if(file.isDir) router.push({path:'/file',query:{path:file.absPath }})
  if(data.avaibleType.includes(file.fileType)){
    handlePreview(file.fileName,file.fileType);
  }else{
    return
  }
}
function handleTouch(file: HyFile) {
    if(file.isDir && !user.$state.isLogin) return
    data.file.current = file
    data.showDrawer = true
}

function sortByKey(array, key, order) {

  return array.sort(function (a, b) {
    var x = a[key]; var y = b[key];
    if (order) {
      return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    } else {
      return ((x < y) ? ((x < y) ? 1 : 0) : -1);
    }
  }

  )
}

</script>

<style lang="scss" scoped>
$row-height: 48px;
$btn-height: 24px;
$table-font-size: 14px;
$big-btn-size:48px;
.main-warper {
  width: 100vw;
  height: 100%;
}

.breadcrumb {
  background: #f8f8f8;
  text-align: left;
  display: block;
  padding-top: 5px;
  padding-bottom: 5px;
  line-height: 24px;
  font-size: 14px;
  color: #238e9c;
  margin: 0;
  height: 100%;

}


.table {
  margin: 2px;
  width: 100vw;
  color: #333;
  font-size: $table-font-size;
  height: auto;
}

.table-header {
  text-align: left;
  background-color: #f0faff;
  font-size: 18px;
  font-weight: bold;
  color: #06a7ff
}

.item-icon {
  width: $row-height;
  height: $row-height;
  line-height: $row-height;

  object-fit: contain;
}



.table-row {
  width: 100vw;
  height: $row-height;
}

.item-link {
  max-width: 36vw;
  height: $row-height;
  display: flex;
  cursor: pointer;
  text-decoration: none;
  color: #303133;
  line-height: $row-height;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


.btn-paste {
  position: fixed;
  right: calc($big-btn-size + 42px);
  bottom: 4vh;
  background-color: #4CAF50;
  /* Green */
  width: $big-btn-size;
  height: $big-btn-size;
  border: none;
  color: white;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  -webkit-transition-duration: 0.4s;
  /* Safari */
  transition-duration: 0.4s;
}

.btn-paste:hover {
  box-shadow: 0 12px 16px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
}

.btn-new-dir {
  position: fixed;
  right: 34px ;
  bottom: 4vh;
  background-color: #238e9c;

  width: $big-btn-size;
  height: $big-btn-size;
  border: none;
  color: white;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 26px;
  margin: 4px 2px;
  cursor: pointer;
  -webkit-transition-duration: 0.4s;
  /* Safari */
  transition-duration: 0.4s;
}

.btn-new-dir:hover {
  box-shadow: 0 12px 16px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
}

.example-showcase .el-loading-mask {
  z-index: 9;
}

.table-row:hover {
  background-color: #f5f5f5;
}

.block-col-2 .demonstration {
  display: block;
  color: var(--el-text-color-secondary);
  font-size: 14px;
  margin-bottom: 20px;
}

.click-fix {
  -moz-user-select: none;
  /*火狐*/
  -webkit-user-select: none;
  /*webkit浏览器*/
  -ms-user-select: none;
  /*IE10*/
  -khtml-user-select: none;
  /*早期浏览器*/
  user-select: none;
}

.empty {
  width: 100vw;
  height: 100%;
}

.upload-demo {
  width: 60vw;
  margin: auto;
  padding-top: 20px;
  padding-bottom: 10px;
}

.btn-group{
  width: auto;
  height: 24px;
}

.ul-mobile {

list-style: none;
padding: 0;
margin: 0;
}

.li-row {
  color: #333;
  height: 48px;
  width: 100vw;
  //overflow: hidden;
}

.li-item {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;
}

.li-item-icon {

  height: 48px;

  text-align: center;
  float: left;

}

.li-item-icon-img {
  object-fit: contain;
  height: 48px;
  width: 100%;
  height: 100%;
}

.li-item-text {
  width: 90%;
  height: 100%;
  display: flex;
  flex-direction: column;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.li-item-text-name {
  font-size: 16px;
  font-weight: bold;
  color: #333;

}

.li-item-text-time {
  font-size: 14px;
  color: #999;
}


.li-item-btn {

  width: 48px;
  height: 48px;
  line-height: 48px;
  float: right;

}
.btn-group-drawer{
  width: 100vw;
  height: 20vh;
}
.li-item-checkbox {
  width: 10px;
  height: 10px;
}



.mobile-btn{
  height: 48px;
  margin: auto;
  width: auto;
}

</style>